﻿package com.nicolasprof.profgallery.thumbs {
	import gs.TweenLite;

	import com.nicolasprof.profgallery.Engine;
	import com.nicolasprof.profgallery.assets.MaskThumbnails;
	import com.nicolasprof.profgallery.thumbs.ArrowControl;
	import com.nicolasprof.profgallery.utils.TooltipHandler;

	import flash.display.*;
	import flash.events.*;

	public class Thumbs extends Sprite {

		public static const HORIZONTAL : String = "horizontal";
		public static const VERTICAL : String = "vertical";
		
		
		private var _thumbHolder:Sprite;
		private var _maskThumbs:MaskThumbnails;
		private var _type:String;
		private var _maxScroll : int;
		private var _curScroll : int;
		private var _listeners : Object;
		private var _selected : Thumbnail;
		private var _control : ThumbControl;
		
		
		public function Thumbs($externalListeners : Object) {
			_listeners = $externalListeners;
			_thumbHolder = new Sprite();
			_maskThumbs = new MaskThumbnails();

			//Display list
			addChild(_thumbHolder);
			addChild(_maskThumbs);
			
			//Actions
			_thumbHolder.cacheAsBitmap = _maskThumbs.cacheAsBitmap = true;
			_thumbHolder.mask = _maskThumbs;
			assignControl();
			registerThumbEvents();
		}
		protected function assignControl() : void {
			var config : XML = Engine.CONFIG_XML;
			switch (String(config.thumbnailControl.@type)) {
				case ThumbControl.ARROW:
					_control = new ArrowControl(this);
					break;
				default :
					_control = new ThumbControl(this);
					break;
			}	
		}
		protected function buildHolder() : void {
			var config : XML = Engine.CONFIG_XML;
			var data : XML = Engine.DATA_XML;
			var columns : int = int(config.thumbnail.@cols);
			var rows : int = int(config.thumbnail.@rows);
			var spacingX : int =  int(config.thumbnail.@spaceX);
			var spacingY : int = int(config.thumbnail.@spaceY);
			var thumbWidth : int = int(config.thumbnail.@width);
			var thumbHeight : int = int(config.thumbnail.@height);
			var th : TooltipHandler = TooltipHandler.getInstance();
			
			_type = config.thumbnail.@type;
			
			var i:int;
			var j:int;
			var k:int;
			var list : XMLList = data.img;
			var len:int = list.length();
			
			for (k = 0; k < len; ++k) {
				var thumb : Thumbnail = new Thumbnail();
				thumb.initiate(thumbWidth, thumbHeight, list[k]);
				thumb.pos = k;
				thumb.draw();
				thumb.loadPhoto();
				_thumbHolder.addChild(thumb);
				thumb.x = i*(spacingX + thumbWidth);
				thumb.y = j*(spacingY + thumbHeight);
				
				if(th.enabled && list[k].title != ""){
					th.add(thumb, list[k].title);
				}
				
				if (_type == Thumbs.VERTICAL) {
					if ((k+1)%columns == 0) {
						i = 0;
						j++;
					} else {
						i++;
					}
				}else if(_type == Thumbs.HORIZONTAL) {
					if ((k+1)%rows == 0) {
						j = 0;
						i++;
					} else {
						j++;
					}
				}
				
			}
				
		}
		internal function calcMaxScroll() : int {
			var config : XML = Engine.CONFIG_XML;
			var columns : int = int(config.thumbnail.@cols);
			var rows : int = int(config.thumbnail.@rows);
			var data : XML = Engine.DATA_XML;
			
			switch (_type){
				case Thumbs.HORIZONTAL : 
					_maxScroll = Math.ceil((data.img.length() - columns*rows) / rows);
					break;
				case Thumbs.VERTICAL : 
					_maxScroll = Math.ceil((data.img.length() - columns*rows) / columns);
					break;
			}
			
			return _maxScroll;
		}
		public function clear() : void {
			clearHolder();
			_curScroll = 0;
			_thumbHolder.x = _thumbHolder.y = 0;
			_control.clear();
		}
		protected function clearHolder() : void {
			var th: TooltipHandler = TooltipHandler.getInstance();
			while(_thumbHolder.numChildren) {
				if(th.enabled){
					th.remove(_thumbHolder.removeChildAt(0));
				}else{
					_thumbHolder.removeChildAt(0);
				}
			}
		}
		protected function declareWheel() : void {
			if (calcMaxScroll() > 0) {
				this.stage.addEventListener(MouseEvent.MOUSE_WHEEL, onWheel, false, 0, true);
			}else{
				this.stage.removeEventListener(MouseEvent.MOUSE_WHEEL, onWheel);
			}
		}
		public function draw() : void {
			//Actions
			declareWheel();
			buildHolder();
			drawMask();
			trigger(0); // Select First
			_control.build();
		}
		protected function drawMask() : void {
			var config : XML = Engine.CONFIG_XML;
			
			var columns : int = int(config.thumbnail.@cols);
			var rows : int = int(config.thumbnail.@rows);
			var spacingX : int =  int(config.thumbnail.@spaceX);
			var spacingY : int = int(config.thumbnail.@spaceY);
			var thumbWidth : int = int(config.thumbnail.@width);
			var thumbHeight : int = int(config.thumbnail.@height);
			var border : int = int(config.thumbnail.@border);
			
			_maskThumbs.x = _maskThumbs.y = -border;
			_maskThumbs.width = columns*thumbWidth + (columns-1)*spacingX + 2 * border;
			_maskThumbs.height = rows *thumbHeight + (rows-1)*spacingY + 2 * border;
		}

		
		/*
		public function dynamicScroll() : void {
			_speed = 1;
			var needScroll:Boolean = false;

			if (_columns*_rows < _data.img.length()) {
				needScroll = true;		
			}
			if (_type == "vertical" && needScroll) {
				_thumbHolder.addEventListener(MouseEvent.MOUSE_MOVE, verticalScroll);
			} else if (_type == "horizontal"  && needScroll) {
				_thumbHolder.addEventListener(MouseEvent.MOUSE_MOVE, horizontalScroll);
			}
		}*/
		
		public function moveHolder() : void {
			var config : XML = Engine.CONFIG_XML;
			var spacingX : int =  int(config.thumbnail.@spaceX);
			var spacingY : int = int(config.thumbnail.@spaceY);
			var thumbWidth : int = int(config.thumbnail.@width);
			var thumbHeight : int = int(config.thumbnail.@height);
			
			if(_type == Thumbs.HORIZONTAL) {
				TweenLite.to(_thumbHolder, 0.5, {x:-_curScroll * (spacingX + thumbWidth)});
			}else{
				TweenLite.to(_thumbHolder, 0.5, {y:-_curScroll * (spacingY + thumbHeight)});
			}
		}
		private function registerThumbEvents() : void {
			this.addEventListener(MouseEvent.CLICK, onClickThumbnail, false, 1, true);
			
			for( var event : String in _listeners){
				this.addEventListener(event, _listeners[event], false, 0, true);
			}
		}	
		private function scrollToView() : void {
			var config : XML = Engine.CONFIG_XML;
			var columns : int = int(config.thumbnail.@cols);
			var rows : int = int(config.thumbnail.@rows);
			var viewZone : int = (_selected.pos + 1) -  columns*rows;
			var alignSep: int = (_type == Thumbs.HORIZONTAL) ? rows : columns;
			
			if(viewZone > 0) {
				_curScroll = Math.ceil(viewZone / alignSep);
			}else {
				_curScroll = 0;
			}
			moveHolder();
			updateScroll();
		}

		public function selectByOffset(offset : int) : void {
			var curPos: int = _selected.pos;
			var len: int = slidesNum;
			curPos += offset;
			if(curPos < 0) {
				curPos += len;
			}else if(curPos >= len) {
				curPos -= len;
			}
			
			trigger(curPos);
			
		}

		public function trigger($index : int) : void {
			var thumb : Thumbnail = _thumbHolder.getChildAt($index) as Thumbnail;
			thumb.dispatchEvent(new MouseEvent(MouseEvent.CLICK));
			scrollToView();
		}
		private function updateScroll() : void {
			/*
			if(_control is ScrollBarControl) {
				ScrollBarControl(_control).updateBar();
			}*/
		}
		/**
		 * EVENTS
		 */
		private function onClickThumbnail(e : MouseEvent) : void {
			if(e.target is Thumbnail){
				//TODO Handle selected Thumbnail and show current selection (Handle Overframe)
				_selected = e.target as Thumbnail;
			}
		}	
		private function onWheel(e : MouseEvent) : void {
			_curScroll -= Math.round(e.delta / 3);
			if(_curScroll < 0) { 
				_curScroll = 0 ;
			}else if(_curScroll > _maxScroll) { 
				_curScroll = _maxScroll ;
			}
			moveHolder();
			
			updateScroll();
			
		}
		
		/*
		private function horizontalScroll(e : MouseEvent) : void {
			var pos:Number;
			pos = -(e.currentTarget.mouseX/_thumbHolder.width)*(_thumbHolder.width-_maskThumbs.width);
			_thumbHolder.x = pos;
		}
		private function verticalScroll(e : MouseEvent) : void {
			var pos:Number;
			pos = -(e.currentTarget.mouseY/_thumbHolder.height)*(_thumbHolder.height-_maskThumbs.height);
			_thumbHolder.x = pos;
		}
		 * 
		 */
		/**
		 * Getters / Setters
		 */
		public function get curScroll() : int {
			return _curScroll;
		}
		public function get slidesNum() : int {
			return Engine.DATA_XML.img.length();
		}
		public function get slideNum() : int {
			return _selected.pos;
		}
		public function get selected() : Thumbnail {
			return _selected;
		}
		public function set curScroll(value : int) : void {
			_curScroll = value;
		}
	}
}